﻿using System;
using System . Collections . Generic;
using System . Linq;
using System . Text;
using System . Threading . Tasks;
using System . Reflection;
using System . Threading;
using System . Runtime . CompilerServices;
using System . Runtime . InteropServices;
using System . IO;
using System . Collections . ObjectModel;

namespace OrangeEndless
{
	public class Core
	{
		public Dictionary<Guid , IMod> DictionaryOfMod { get; private set; }

		Collection<string> ModFiles;

		public async Task<ReadOnlyCollection<ModInfo>> GetModList ( )
		{
			return await Task . Run ( ( ) =>
			{
				List<ModInfo> listofmod = new List<ModInfo> ( );
				foreach ( var fil in ModFiles )
				{
					var types = ( Assembly . LoadFrom ( fil ) ) . GetTypes ( );
					foreach ( var typ in types )
					{
						if ( typ . IsSubclassOf ( typeof ( IMod ) ) )
						{
							ModAttribute Att = Attribute . GetCustomAttribute ( typ , typeof ( ModAttribute ) ) as ModAttribute;
							ModInfo temp=new ModInfo
							{
								Name = Att . Name ,
								Author = Att . Author ,
								Introduction = Att . Introduction ,
								Id = Att . Id ,
								Demand = Att . Demand ,
								ModType = typ
							};
							listofmod . Add ( temp );
						}
					}
				}
				return new ReadOnlyCollection<ModInfo> ( listofmod );
			} );

		}

		public void LoadMod ( Collection<ModInfo> modtoload )
		{
			if ( modtoload != null )
			{
				for ( int i = 0 ; i < modtoload . Count ; i++ )
				{
					foreach ( var modinfo in modtoload )
					{
						Collection<IMod> Demend=new Collection<IMod> ( );
						bool CanLoad=true;
						foreach ( var dem in modinfo . Demand )
						{
							if ( DictionaryOfMod . ContainsKey ( dem ) )
							{
								Demend . Add ( DictionaryOfMod [ dem ] );
							}
							else
							{
								CanLoad = false;
								break;
							}
						}
						if ( CanLoad )
						{

							DictionaryOfMod . Add ( modinfo . Id , Activator . CreateInstance ( modinfo . ModType , Demend , this ) as IMod );
						}
					}
				}
			}
		}

		public Core ( Collection<string> modfiles )
		{
			DictionaryOfMod = new Dictionary<Guid , IMod> ( );
			ModFiles = modfiles;
		}

		public async void Start ( )
		{
			foreach ( var item in DictionaryOfMod . Values )
			{
				try
				{
					await item . Start ( );

				}
				catch ( Exception )
				{

					throw;
				}
			}
		}

		public async void Suspend ( )
		{
			var Ts=new List<Task> ( );
			foreach ( var item in DictionaryOfMod . Values )
			{
				Ts . Add ( item . Suspend ( ) );
			}
			await Task . WhenAll ( Ts );
		}
	}
}
